package com.longway.core.toolbox.wdp.api;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.JsonKit;
import com.longway.core.toolbox.utils.RetryUtils.ResultCheck;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


@SuppressWarnings("unchecked")
public class AuthorizationInfo implements ResultCheck, Serializable {
	private static final long serialVersionUID = -7586100118379533869L;
	private String authorizer_appid;
	private String authorizer_access_token;
    private Integer expires_in;
    private String authorizer_refresh_token;
    private List<Func> func_info;
	private Integer errcode;
    private String errmsg;
    private Long expiredTime;
    private String json;
    
    public AuthorizationInfo(){
    	
    }

    public AuthorizationInfo(String jsonStr) {
        this.json = jsonStr;

        try {
            Map<String, Object> temp = JsonKit.parse(jsonStr, Map.class);
            Map<String, Object> authorizationInfo = (Map<String, Object>)temp.get("authorization_info");
            authorizer_appid = (String) authorizationInfo.get("authorizer_appid");
            authorizer_access_token = (String) authorizationInfo.get("authorizer_access_token");
            expires_in = (Integer) authorizationInfo.get("expires_in");
            authorizer_refresh_token = (String) authorizationInfo.get("authorizer_refresh_token");
            JSONArray funcs = (JSONArray)authorizationInfo.get("func_info");
            JSONObject func = null;
            func_info = new ArrayList<>();
            for (int i=0;i<funcs.size();i++) {
            	func = funcs.getJSONObject(i);
            	Func f = new Func();
            	if(func.get("funcscope_category")!=null){
            		JSONObject category =	(JSONObject)func.get("funcscope_category");
            		f.setFuncscopeCategory(category.getInteger("id"));
            	}
            	if(func.get("confirm_info")!=null){
            		JSONObject confirm = (JSONObject)func.get("confirm_info");
            		ConfirmInfo cif = new ConfirmInfo();
                	cif.setNeedConfirm(confirm.getInteger("need_confirm"));
                	cif.setAlreadyConfirm(confirm.getInteger("already_confirm"));
                	cif.setCanConfirm(confirm.getInteger("can_confirm"));
                	f.setConfirmInfo(cif);
            	}
            	func_info.add(f);
			}
            errcode = (Integer) authorizationInfo.get("errcode");
            errmsg = (String) authorizationInfo.get("errmsg");

            if (expires_in != null) {
            	// expires_in - 60  用于控制在 authorizer_access_token 过期之前 60 秒就 "主动" 使用刷新令牌再次获取authorizer_access_token
                expiredTime = System.currentTimeMillis() + ((expires_in - 60) * 1000);
            }
            
            // 用户缓存时还原
            if (temp.containsKey("expiredTime")) {
                 expiredTime = (Long) temp.get("expiredTime");
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String getJson() {
        return json;
    }

    public String getCacheJson() {
        Map<String, Object> temp = JsonKit.parse(json, Map.class);
        temp.put("expiredTime", expiredTime);
        temp.remove("expires_in");
        return JsonKit.toJson(temp);
    }

    public boolean isAvailable() {
        if (expiredTime == null) {
            return false;
        }
        if (errcode != null) {
            return false;
        }
        if (expiredTime < System.currentTimeMillis()) {
            return false;
        }
        return authorizer_access_token != null;
    }

    public Integer getExpiresIn() {
        return expires_in;
    }

    public String getAuthorizerAppid() {
		return authorizer_appid;
	}

	public void setAuthorizerAppid(String authorizer_appid) {
		this.authorizer_appid = authorizer_appid;
	}

	public String getAuthorizerAccessToken() {
		return authorizer_access_token;
	}

	public String getAuthorizerRefreshToken() {
		return authorizer_refresh_token;
	}

	public Long getExpiredTime() {
        return expiredTime;
    }

    public Integer getErrorCode() {
        return errcode;
    }

    public String getErrorMsg() {
        if (errcode != null) {
            String result = ReturnCode.get(errcode);
            if (result != null) {
                return result;
            }
        }
        return errmsg;
    }

    @Override
    public boolean matching() {
        return isAvailable();
    }

	public void setAuthorizerAccessToken(String authorizer_access_token) {
		this.authorizer_access_token = authorizer_access_token;
	}


	public void setExpiresIn(Integer expires_in) {
		this.expires_in = expires_in;
	}

	public void setAuthorizerRefreshToken(String authorizer_refresh_token) {
		this.authorizer_refresh_token = authorizer_refresh_token;
	}

	public void setExpiredTime(Long expiredTime) {
		this.expiredTime = expiredTime;
	}

	public List<Func> getFuncInfo() {
		return func_info;
	}

	public void setFuncInfo(List<Func> func_info) {
		this.func_info = func_info;
	}
}
